package com.rd.sys.servlet.auth;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.rd.sys.common.base.CommonConstants;
import com.rd.sys.common.utils.CommonUtils;
import com.rd.sys.common.utils.GetWebConfig;
import com.rd.sys.common.utils.JacksonMapper;
import com.rd.sys.dto.commmon.base.EyeResult;

/**
 * 鉴权基础Servlet类
 */
public class AuthBaseServlet extends HttpServlet {
    private static final long serialVersionUID = 8722471919334049452L;
    protected static final Logger logger = LoggerFactory.getLogger(AuthBaseServlet.class);

    /** 随机码获取保存MAP (为兼容客户端无法使用SessionID) */
    private static final Cache<String, String> loginCodeCache = CacheBuilder.newBuilder()
            .maximumSize(CommonConstants.UserConstats.AUTH_RAND_SAVE_NUMBBER)
            .expireAfterWrite(CommonConstants.UserConstats.AUTH_RAND_SAVE_TIME, TimeUnit.SECONDS).build();

    /** 数据分析主页 */
    protected final String analysisIndexUrl = GetWebConfig.getValue("auth.redirect.analysis.index.url");

    /** 数据分析方案页 */
    protected final String analysisSchemeUrl = GetWebConfig.getValue("auth.redirect.analysis.scheme.url");

    /** 用户项目所在基础路径 */
    protected final String userProjectBasePath = CommonUtils.judgeConfigPath(GetWebConfig
            .getValue("user.project.base.path"));

    /**
     * 获取Service层服务实例
     * 
     * @param beanName
     * @return
     */
    protected Object getService(String beanName) {
        WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
        return context.getBean(beanName);
    }

    /**
     * 判断用户的某个方案是否存在
     * 
     * @param userCode
     * @param projectCode
     * @param schemeCode
     * @return
     * @throws Exception
     */
    protected boolean isSchemeExist(String userCode, String projectCode, String schemeCode) throws Exception {
        File file = new File(userProjectBasePath + CommonConstants.SysParamConstants.FILE_SEPARATOR + userCode
                + CommonConstants.SysParamConstants.FILE_SEPARATOR + projectCode
                + CommonConstants.SysParamConstants.FILE_SEPARATOR + schemeCode);
        // 判断该路径下是否存在方案目录
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 发送响应消息
     * 
     * @param resultContent
     * @param resp
     * @throws IOException
     */
    protected void sendResponse(String resultContent, HttpServletResponse resp) throws IOException {
        resp.setCharacterEncoding(CommonConstants.SysParamConstants.SYS_CHARSET);
        resp.getWriter().print(resultContent);
    }

    /**
     * 发送响应消息(直接响应)
     * 
     * @param result
     * @param resp
     * @throws IOException
     */
    protected void sendResponse(EyeResult result, HttpServletResponse resp) throws IOException {
        resp.setHeader("Content-Type", "text/plain; charset=" + CommonConstants.SysParamConstants.SYS_CHARSET);
        resp.setCharacterEncoding(CommonConstants.SysParamConstants.SYS_CHARSET);
        String message = JacksonMapper.bean2Json(result);
        logger.info("the response message is: " + message);
        resp.getWriter().print(message);
    }

    /**
     * 发送响应消息(失败时重定向)
     * 
     * @param result
     * @param req
     * @param resp
     * @throws IOException
     */
    protected void sendResponse(EyeResult result, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        if (EyeResult.ResultDefine.COMMON_SUCCESS.getCode().equals(result.getRspCode())) { // 做个保护,当成功响应时
            sendResponse(result, resp);
        } else {
            String message = JacksonMapper.bean2Json(result);
            logger.info("the response message is: " + message);
            // 按客户端要求,当发生错误时,返回定制的错误页面,不再直接响应错误码
            String redirectUrl = "http://" + req.getHeader("Host") + req.getContextPath() + "/msgClient.jsp?rspCode="
                    + result.getRspCode();
            resp.sendRedirect(redirectUrl);
        }
    }

    /**
     * 获取键值对 随机码-用户编码
     * 
     * @param loginCode
     *            随机码
     * @return
     */
    protected String queryLoginCode(String loginCode) throws Exception {
//        String userCode = loginCodeCache.get(loginCode, new Callable<String>() {
//            @Override
//            public String call() throws Exception {
////                return "EV201701010001"; // 键不存在默认就返回null
//                return null;
//            }
//        });
//        return userCode;
        return "EV201701010001";
    }

    /**
     * 设置键值对 随机码-用户编码
     * 
     * @param userCode
     *            用户唯一编码
     * @param loginCode
     *            随机码
     */
    protected void putLoginCode(String loginCode, String userCode) {
        loginCodeCache.put(loginCode, userCode);
    }
}
